﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Weazel.Gezel.Model.Errors;

namespace Weazel.Gezel.Parser.Test
{
	/// <summary>
	/// Summary description for TestTokenizerPosition
	/// </summary>
	[TestClass]
	public class TestTokenizerPosition
	{
		[TestMethod]
		public void TestTokenizerPosition1()
		{
			string description =
				"dp mydp(in x : ns(1)) { \n" +
				"	sfg run {					 		 \n" +
				"		y = x;							 \n" +
				"	}											 \n" +
				"}											 \n";

			Tokenizer t = new Tokenizer(description);

			// "dp" from 0 to 1 on line 1
			Assert.AreEqual(Token.Dp, t.CurrentToken);
		
			Assert.AreEqual<uint>(1, t.CurrentStartPosition.LineNumber);
			Assert.AreEqual<uint>(1, t.CurrentStartPosition.ColumnNumber);

			Assert.AreEqual<uint>(1, t.CurrentEndPosition.LineNumber);
			Assert.AreEqual<uint>(2, t.CurrentEndPosition.ColumnNumber);

			t.NextToken();

			// "mydp" from 3 to 6 on line 1
			Assert.AreEqual(Token.Identifier, t.CurrentToken);

			Assert.AreEqual<uint>(1, t.CurrentStartPosition.LineNumber);
			Assert.AreEqual<uint>(4, t.CurrentStartPosition.ColumnNumber);

			Assert.AreEqual<uint>(1, t.CurrentEndPosition.LineNumber);
			Assert.AreEqual<uint>(7, t.CurrentEndPosition.ColumnNumber);

			t.NextToken();

			// "(" from 7 on line 1
			Assert.AreEqual(Token.LeftParenthesis, t.CurrentToken);

			Assert.AreEqual<uint>(1, t.CurrentStartPosition.LineNumber);
			Assert.AreEqual<uint>(8, t.CurrentStartPosition.ColumnNumber);

			Assert.AreEqual<uint>(1, t.CurrentEndPosition.LineNumber);
			Assert.AreEqual<uint>(8, t.CurrentEndPosition.ColumnNumber);

			t.NextToken();

			// "in" from 8 to 9 on line 1
			Assert.AreEqual(Token.In, t.CurrentToken);

			Assert.AreEqual<uint>(1, t.CurrentStartPosition.LineNumber);
			Assert.AreEqual<uint>(9, t.CurrentStartPosition.ColumnNumber);

			Assert.AreEqual<uint>(1, t.CurrentEndPosition.LineNumber);
			Assert.AreEqual<uint>(10, t.CurrentEndPosition.ColumnNumber);

			t.NextToken();

			// "x" from 10 on line 1
			Assert.AreEqual(Token.Identifier, t.CurrentToken);

			Assert.AreEqual<uint>(1, t.CurrentStartPosition.LineNumber);
			Assert.AreEqual<uint>(12, t.CurrentStartPosition.ColumnNumber);

			Assert.AreEqual<uint>(1, t.CurrentEndPosition.LineNumber);
			Assert.AreEqual<uint>(12, t.CurrentEndPosition.ColumnNumber);

			t.NextToken();

			// ":" from 10 on line 1
			Assert.AreEqual(Token.Colon, t.CurrentToken);

			Assert.AreEqual<uint>(1, t.CurrentStartPosition.LineNumber);
			Assert.AreEqual<uint>(14, t.CurrentStartPosition.ColumnNumber);

			Assert.AreEqual<uint>(1, t.CurrentEndPosition.LineNumber);
			Assert.AreEqual<uint>(14, t.CurrentEndPosition.ColumnNumber);

			// skip t0 next line
			t.NextToken();	// ns
			t.NextToken();	// (
			t.NextToken();	// number
			t.NextToken();	// )
			t.NextToken();  // )
			t.NextToken();  // {

			t.NextToken();

			Assert.AreEqual(Token.Sfg, t.CurrentToken);

			Assert.AreEqual<uint>(2, t.CurrentStartPosition.LineNumber);
			Assert.AreEqual<uint>(2, t.CurrentStartPosition.ColumnNumber);

			Assert.AreEqual<uint>(2, t.CurrentEndPosition.LineNumber);
			Assert.AreEqual<uint>(4, t.CurrentEndPosition.ColumnNumber);

			t.NextToken();

			// "run" from 5 to 7 on line 2
			Assert.AreEqual(Token.Identifier, t.CurrentToken);

			Assert.AreEqual<uint>(2, t.CurrentStartPosition.LineNumber);
			Assert.AreEqual<uint>(6, t.CurrentStartPosition.ColumnNumber);

			Assert.AreEqual<uint>(2, t.CurrentEndPosition.LineNumber);
			Assert.AreEqual<uint>(8, t.CurrentEndPosition.ColumnNumber);
		}
	}
}
